﻿
#region Copyright & License
// --------------------------
// Copyright 2008 Daniel Gray
// --------------------------
// This file is part of Kale.
//
// Kale is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Kale is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with Kale.  If not, see <http://www.gnu.org/licenses/>.
#endregion
#region File details
// --------------------------------------------------------
// Filename          : SessionSerializer.cs
// Author            : Daniel Gray
// Created           : 07/05/2008
// --------------------------------------------------------
#endregion
            
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using Kale.Core.Security;
using System.IO;
using Kale.Core;

namespace Kale.Db.Sql
{
   internal class SessionSerializer
   {
      private BinaryFormatter _formatter = new BinaryFormatter();

      internal void SerializeSession(Session session, KaleModelDataContext context)
      {
         ICollection<KeyValuePair<string,object>> collection = session as ICollection<KeyValuePair<string, object>>;

         foreach (KeyValuePair<string, object> pair in collection)
         {
            // get an existing one - or create it...
            SessionObject dbObject = (from so in context.SessionObjects where so.ObjectKey == pair.Key && so.SessionUid == session.Uid select so).FirstOrDefault();

            if (dbObject == null)
            {
               dbObject = new SessionObject();
               dbObject.Uid = Guid.NewGuid();
               dbObject.SessionUid = session.Uid;
               dbObject.ObjectKey = pair.Key;
               context.SessionObjects.InsertOnSubmit(dbObject);
            }

            // serialize the object to a byte array
            dbObject.ObjectBinary = SerializeObject(pair.Value);
            
         }
         // fin!
         context.SubmitChanges();
      }

      private byte[] SerializeObject(object obj)
      {
         using (MemoryStream ms = new MemoryStream())
         {
            _formatter.Serialize(ms, obj);
            ms.Flush();
            ms.Seek(0, SeekOrigin.Begin);

            byte[] data = new byte[ms.Length];
            Utility.ReadWholeArray(ms, data);
            return data;
         }
      }

      private object DeserializeObject(byte[] data)
      {
         using (MemoryStream ms = new MemoryStream())
         {
            Utility.WriteWholeArray(ms, data);
            ms.Flush();
            ms.Seek(0, SeekOrigin.Begin);

            return _formatter.Deserialize(ms);
         }
      }

      internal void DeserializeSession(Session session, KaleModelDataContext context)
      {
         IDictionary<string, object> dictionary = session as IDictionary<string, object>;

         foreach (SessionObject dbObject in context.SessionObjects.Where(s=>s.SessionUid == session.Uid))
         {
            dictionary.Add(dbObject.ObjectKey, DeserializeObject(dbObject.ObjectBinary.ToArray()));
         }
      }
   }
}
